#include <wx/wx.h>
#include "panel_compressor.h"
#include "MyCommon.h"
#include "DataSave.h"

#define SLI_MAX(max,min,step) (int)((max - min) / step)


wxDEFINE_EVENT(myEVT_COMPRESSOR, MyEventCompressor);
wxDEFINE_EVENT(myEVT_COMPRESSOR_THRESHOLD, MyEventCompressor);
wxDEFINE_EVENT(myEVT_COMPRESSOR_RELEASE_TIME, MyEventCompressor);
wxDEFINE_EVENT(myEVT_COMPRESSOR_POSTGAIN, MyEventCompressor);
wxDEFINE_EVENT(myEVT_COMPRESSOR_RATIO, MyEventCompressor);
wxDEFINE_EVENT(myEVT_COMPRESSOR_ATTACK_TIME, MyEventCompressor);
wxDEFINE_EVENT(myEVT_COMPRESSOR_ENABLE, MyEventCompressor);


// wxBEGIN_EVENT_TABLE(PanelCompressor, wxPanel)
//     EVT_SLIDER(PanelCompressor::ID_SLI_ATTACK_TIME, PanelCompressor::OnSliderChange)
//     EVT_SLIDER(PanelCompressor::ID_SLI_THRESHOLD, PanelCompressor::OnSliderChange)
//     EVT_SLIDER(PanelCompressor::ID_SLI_RELEASE_TIME, PanelCompressor::OnSliderChange)
//     EVT_SLIDER(PanelCompressor::ID_SLI_RATIO, PanelCompressor::OnSliderChange)
//     EVT_TEXT_ENTER(PanelCompressor::ID_TXT_ATTACK_TIME,PanelCompressor::OnTextEnter)
//     EVT_TEXT_ENTER(PanelCompressor::ID_TXT_THRESHOLD,PanelCompressor::OnTextEnter)
//     EVT_TEXT_ENTER(PanelCompressor::ID_TXT_RELEASE_TIME,PanelCompressor::OnTextEnter)
//     EVT_TEXT_ENTER(PanelCompressor::ID_TXT_RATIO,PanelCompressor::OnTextEnter)
//     EVT_CHECKBOX(PanelCompressor::ID_CHK_SWITCH,PanelCompressor::OnChkChange)
// wxEND_EVENT_TABLE()


PanelCompressor::PanelCompressor(const wxString &title, wxXmlNode *node, wxWindowID id, wxWindow *parent)
    : wxPanel(parent,id,wxDefaultPosition,wxDefaultSize,wxTAB_TRAVERSAL)
{
    SetSize(200, 300);

    root_node = node;
    select_index = 0;

    wxWindowID cid = id + 1;
    ID_TXT_ATTACK_TIME = cid++;
    ID_TXT_THRESHOLD = cid++;
    ID_TXT_RELEASE_TIME = cid++;
    ID_TXT_POSTGAIN = cid++;
    ID_TXT_RATIO = cid++;
    ID_SLI_ATTACK_TIME = cid++;
    ID_SLI_THRESHOLD = cid++;
    ID_SLI_RELEASE_TIME = cid++;
    ID_SLI_POSTGAIN = cid++;
    ID_SLI_RATIO = cid++;
    ID_CHK_SWITCH = cid++;
    ID_CHO_PRESET = cid ++;

    wxCheckBox      *chk_enable            = new wxCheckBox(this,   ID_CHK_SWITCH,            "Enable");
    wxTextCtrl      *txt_threshold             = new wxTextCtrl(this,   ID_TXT_THRESHOLD,             mDoubleToString(threshold_min),             wxDefaultPosition, wxDefaultSize,                 wxTE_PROCESS_ENTER);
    wxTextCtrl      *txt_release_time          = new wxTextCtrl(this,   ID_TXT_RELEASE_TIME,          mDoubleToString(release_time_min),          wxDefaultPosition, wxDefaultSize,                 wxTE_PROCESS_ENTER);
    wxTextCtrl      *txt_postgain       = new wxTextCtrl(this,   ID_TXT_POSTGAIN,       mDoubleToString(postgain_min),       wxDefaultPosition, wxDefaultSize,                 wxTE_PROCESS_ENTER);
    wxTextCtrl      *txt_ratio = new wxTextCtrl(this,   ID_TXT_RATIO, mDoubleToString(ratio_min), wxDefaultPosition, wxDefaultSize,                 wxTE_PROCESS_ENTER);
    wxTextCtrl      *txt_attack_time   = new wxTextCtrl(this,   ID_TXT_ATTACK_TIME,   mDoubleToString(attack_time_min),   wxDefaultPosition, wxDefaultSize,                 wxTE_PROCESS_ENTER);
    wxStaticText    *lab_threshold             = new wxStaticText(this, wxID_ANY,                 "Threshold:");
    wxStaticText    *lab_release_time          = new wxStaticText(this, wxID_ANY,                 "ReleaseTime:");
    wxStaticText    *lab_postgain       = new wxStaticText(this, wxID_ANY,                 "PostGain:");
    wxStaticText    *lab_ratio = new wxStaticText(this, wxID_ANY,                 "Ratio(Hz):");
    wxStaticText    *lab_attack_time   = new wxStaticText(this, wxID_ANY,                 "AttackTime(Hz):");
    wxStaticText    *lab_preset            = new wxStaticText(this, wxID_ANY,                 "Preset:");
    wxSlider        *sli_attack_time   = new wxSlider(this,     ID_SLI_ATTACK_TIME,   0,                                      0,                 SLI_MAX(attack_time_max,   attack_time_min,   attack_time_step));
    wxSlider        *sli_threshold             = new wxSlider(this,     ID_SLI_THRESHOLD,             0,                                      0,                 SLI_MAX(threshold_max,             threshold_min,             threshold_step));
    wxSlider        *sli_release_time          = new wxSlider(this,     ID_SLI_RELEASE_TIME,          0,                                      0,                 SLI_MAX(release_time_max,          release_time_min,          release_time_step));
    wxSlider        *sli_postgain       = new wxSlider(this,     ID_SLI_POSTGAIN,       0,                                      0,                 SLI_MAX(postgain_max,       postgain_min,       postgain_step));
    wxSlider        *sli_ratio = new wxSlider(this,     ID_SLI_RATIO, 0,                                      0,                 SLI_MAX(ratio_max, ratio_min, ratio_step));
    wxFlexGridSizer *layout_main           = new wxFlexGridSizer(7, 3,                        wxSize(3,                               3));
    wxChoice        *cho_preset            = new wxChoice(this,     ID_CHO_PRESET);

    sli_attack_time->SetMinSize(wxSize(100, -1));
    sli_attack_time->SetTick(1);
    sli_threshold->SetMinSize(wxSize(100, -1));
    sli_release_time->SetMinSize(wxSize(100, -1));
    sli_postgain->SetMinSize(wxSize(100, -1));
    sli_ratio->SetMinSize(wxSize(100, -1));
    txt_attack_time->SetMinSize(wxSize(50, -1));
    txt_attack_time->SetMaxSize(wxSize(100, -1));
    txt_threshold->SetMinSize(wxSize(50, -1));
    txt_threshold->SetMaxSize(wxSize(100, -1));
    txt_release_time->SetMinSize(wxSize(50, -1));
    txt_release_time->SetMaxSize(wxSize(100, -1));
    txt_postgain->SetMinSize(wxSize(50, -1));
    txt_postgain->SetMaxSize(wxSize(100, -1));
    txt_ratio->SetMinSize(wxSize(50, -1));
    txt_ratio->SetMaxSize(wxSize(100, -1));

    sli_release_time->Bind(wxEVT_SLIDER, &PanelCompressor::OnSliderChange, this, ID_SLI_RELEASE_TIME);
    sli_postgain->Bind(wxEVT_SLIDER, &PanelCompressor::OnSliderChange, this, ID_SLI_POSTGAIN);
    sli_attack_time->Bind(wxEVT_SLIDER, &PanelCompressor::OnSliderChange, this, ID_SLI_ATTACK_TIME);
    sli_threshold->Bind(wxEVT_SLIDER, &PanelCompressor::OnSliderChange, this, ID_SLI_THRESHOLD);
    sli_ratio->Bind(wxEVT_SLIDER, &PanelCompressor::OnSliderChange, this, ID_SLI_RATIO);
    txt_attack_time->Bind(wxEVT_TEXT_ENTER, &PanelCompressor::OnTextEnter, this, ID_TXT_ATTACK_TIME);
    txt_threshold->Bind(wxEVT_TEXT_ENTER, &PanelCompressor::OnTextEnter, this, ID_TXT_THRESHOLD);
    txt_release_time->Bind(wxEVT_TEXT_ENTER, &PanelCompressor::OnTextEnter, this, ID_TXT_RELEASE_TIME);
    txt_postgain->Bind(wxEVT_TEXT_ENTER, &PanelCompressor::OnTextEnter, this, ID_TXT_POSTGAIN);
    txt_ratio->Bind(wxEVT_TEXT_ENTER, &PanelCompressor::OnTextEnter, this, ID_TXT_RATIO);
    chk_enable->Bind(wxEVT_CHECKBOX, &PanelCompressor::OnChkChange, this, ID_CHK_SWITCH);
    cho_preset->Bind(wxEVT_CHOICE,        &PanelCompressor::OnCombChange,   this, ID_CHO_PRESET);

    // cho_preset->Append("wah-1");
    // cho_preset->Append("wah-2");
    // cho_preset->Append("wah-3");
    // cho_preset->Append("wah-4");
    // cho_preset->Append("wah-5");
    // cho_preset->Append("wah-6");
    // cho_preset->Select(select_index);


    layout_main->Add(chk_enable  ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->AddStretchSpacer();
    layout_main->AddStretchSpacer();
    layout_main->Add(lab_threshold     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(txt_threshold     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(sli_threshold     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(lab_release_time,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(txt_release_time,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(sli_release_time,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(lab_postgain,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(txt_postgain,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(sli_postgain,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(lab_ratio    ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(txt_ratio    ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(sli_ratio    ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(lab_attack_time     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(txt_attack_time     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(sli_attack_time     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(lab_preset,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(cho_preset,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->AddStretchSpacer();
    layout_main->AddGrowableCol(0,0);
    layout_main->AddGrowableCol(1,0);
    layout_main->AddGrowableCol(2,1);

    SetSizer(layout_main);

    paneInfo.Caption(title);
    paneInfo.Dock();
    paneInfo.Dockable(true);
    paneInfo.CloseButton(true);
    paneInfo.MaximizeButton(true);
    paneInfo.MinimizeButton(true);
    paneInfo.DestroyOnClose(false);
    // paneInfo.Direction(wxLeft);

    param_event.SetEventObject(this);

    param.threshold = threshold_min;
    param.release_time = release_time_min;
    param.postgain = postgain_min;
    param.ratio = ratio_min;
    param.attack_time = attack_time_min;
    param.enable = false;

    // wxString str;
    // wxString select_name = attr_name_preset_default;
    // if(DataSave::NodeAttributesGetValue(root_node,attr_name_select,str))
    // {
    //     select_name = str;
    // }
    // else
    // {
    //     DataSave::NodeAttributesSetValue(root_node,attr_name_select,attr_name_preset_default);
    // }
    preset_node = nullptr;
    if(cho_preset->GetCount() > 0)
    {
        preset_node = SelectPreset(cho_preset->GetString(select_index));
    }
}


wxAuiPaneInfo &PanelCompressor::GetPaneInfo()
{
    return paneInfo;
}


void PanelCompressor::SetShow(bool show)
{
    Show(show);
}


void PanelCompressor::OnSliderChange(wxCommandEvent& event)
{
    int id = event.GetId();
    // switch(id)
    {
        if(id == ID_SLI_ATTACK_TIME)
        {
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_ATTACK_TIME),wxSlider);
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_ATTACK_TIME),wxTextCtrl);
            double sv = sli->GetValue();
            double v = attack_time_min + sv / (1/attack_time_step);
            txt->SetValue(mDoubleToString(v));
            param.attack_time = v;
            TrigerEvent(EV_ATTACK_TIME);
        }
        else if(id ==  ID_SLI_THRESHOLD)
        {
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_THRESHOLD),wxSlider);
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_THRESHOLD),wxTextCtrl);
            double sv = sli->GetValue();
            double v = threshold_min + sv / (1/threshold_step);
            txt->SetValue(mDoubleToString(v));
            param.threshold = v;
            TrigerEvent(EV_THRESHOLD);
        }
        else if(id ==  ID_SLI_RATIO)
        {
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_RATIO),wxSlider);
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_RATIO),wxTextCtrl);
            double sv = sli->GetValue();
            double v = ratio_min + sv / (1/ratio_step);
            txt->SetValue(mDoubleToString(v));
            param.ratio = v;
            TrigerEvent(EV_RATIO);
        }
        else if(id ==  ID_SLI_RELEASE_TIME)
        {
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_RELEASE_TIME),wxSlider);
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_RELEASE_TIME),wxTextCtrl);
            double sv = sli->GetValue();
            double v = release_time_min + sv / (1/release_time_step);
            txt->SetValue(mDoubleToString(v));
            param.release_time = v;
            TrigerEvent(EV_RELEASE_TIME);
        }
        else if(id ==  ID_SLI_POSTGAIN)
        {
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_POSTGAIN),wxSlider);
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_POSTGAIN),wxTextCtrl);
            double sv = sli->GetValue();
            double v = postgain_min + sv / (1/postgain_step);
            txt->SetValue(mDoubleToString(v));
            param.postgain = v;
            TrigerEvent(EV_POSTGAIN);
        }
    }
}

void PanelCompressor::OnTextEnter(wxCommandEvent& event)
{
    int id = event.GetId();
    // switch(id)
    {
        if(id == ID_TXT_ATTACK_TIME)
        {
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_ATTACK_TIME),wxTextCtrl);
            double v ;
            if(txt->GetValue().ToDouble(&v) == true)
            {
                if((v >= attack_time_min) && (v <= attack_time_max))
                {
                    param.attack_time = v;
                }
            }
            double sv = (param.attack_time - attack_time_min) * (1/attack_time_step);
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_ATTACK_TIME),wxSlider);
            sli->SetValue(sv);
            TrigerEvent(EV_ATTACK_TIME);
        }
        else if(id ==  ID_TXT_THRESHOLD)
        {
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_THRESHOLD),wxTextCtrl);
            double v ;
            if(txt->GetValue().ToDouble(&v) == true)
            {
                if((v >= threshold_min) && (v <= threshold_max))
                {
                    param.threshold = v;
                }
            }
            double sv = (param.threshold - threshold_min) * (1/threshold_step);
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_THRESHOLD),wxSlider);
            sli->SetValue(sv);
            TrigerEvent(EV_THRESHOLD);
        }
        else if(id ==  ID_TXT_RATIO)
        {
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_RATIO),wxTextCtrl);
            double v ;
            if(txt->GetValue().ToDouble(&v) == true)
            {
                if((v >= ratio_min) && (v <= ratio_max))
                {
                    param.ratio = v;
                }
            }
            double sv = (param.ratio - ratio_min) * (1/ratio_step);
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_RATIO),wxSlider);
            sli->SetValue(sv);
            TrigerEvent(EV_RATIO);
        }
        else if(id ==  ID_TXT_RELEASE_TIME)
        {
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_RELEASE_TIME),wxTextCtrl);
            double v ;
            if(txt->GetValue().ToDouble(&v) == true)
            {
                if((v >= release_time_min) && (v <= release_time_max))
                {
                    param.release_time = v;
                }
            }
            double sv = (param.release_time - release_time_min) * (1/release_time_step);
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_RELEASE_TIME),wxSlider);
            sli->SetValue(sv);
            TrigerEvent(EV_RELEASE_TIME);
        }
        else if(id ==  ID_TXT_POSTGAIN)
        {
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_POSTGAIN),wxTextCtrl);
            double v ;
            if(txt->GetValue().ToDouble(&v) == true)
            {
                if((v >= postgain_min) && (v <= postgain_max))
                {
                    param.postgain = v;
                }
            }
            double sv = (param.postgain - postgain_min) * (1/postgain_step);
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_POSTGAIN),wxSlider);
            sli->SetValue(sv);
            TrigerEvent(EV_POSTGAIN);
        }
    }
}

void PanelCompressor::OnChkChange(wxCommandEvent &event)
{
    int id = event.GetId();
    // switch(id)
    {
        if(id == ID_CHK_SWITCH)
        {
            wxCheckBox *chk = wxDynamicCast(FindWindowById(ID_CHK_SWITCH),wxCheckBox);
            param.enable = chk->IsChecked();
            TrigerEvent(EV_ENABLE);
        }
    }
}

void PanelCompressor::OnCombChange(wxCommandEvent& event)
{
    wxChoice *cmb = wxDynamicCast(FindWindowById(ID_CHO_PRESET),wxChoice);
    int i = cmb->GetSelection();
    if((unsigned int)i < cmb->GetCount())
    {
        select_index = i;
        preset_node = SelectPreset(cmb->GetString(i));
        param_event.SetPresetIndex(select_index);
        param_event.SetEventType(myEVT_COMPRESSOR);
        ProcessWindowEvent(param_event);
    }
}


double PanelCompressor::SetParamAttackTime(double v)
{
    if(v < attack_time_min)
    {
        v = attack_time_min;
    }
    else if(v > attack_time_max)
    {
        v = attack_time_max;
    }
    double sv = (v - attack_time_min) * (1/attack_time_step);
    wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_ATTACK_TIME),wxSlider);
    sli->SetValue(sv);
    wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_ATTACK_TIME),wxTextCtrl);
    txt->SetValue(mDoubleToString(v));
    param.attack_time = v;
    param_event.SetAttackTime(v);
    return v;
}

double PanelCompressor::SetParamThreshold(double v)
{
    if(v < threshold_min)
    {
        v = threshold_min;
    }
    else if(v > threshold_max)
    {
        v = threshold_max;
    }
    double sv = (v - threshold_min) * (1/threshold_step);
    wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_THRESHOLD),wxSlider);
    sli->SetValue(sv);
    wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_THRESHOLD),wxTextCtrl);
    txt->SetValue(mDoubleToString(v));
    param.threshold = v;
    param_event.SetThreshold(v);
    return v;
}

double PanelCompressor::SetParamRatio(double v)
{
    if(v < ratio_min)
    {
        v = ratio_min;
    }
    else if(v > ratio_max)
    {
        v = ratio_max;
    }
    double sv = (v - ratio_min) * (1/ratio_step);
    wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_RATIO),wxSlider);
    sli->SetValue(sv);
    wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_RATIO),wxTextCtrl);
    txt->SetValue(mDoubleToString(v));
    param.ratio = v;
    param_event.SetRatio(v);
    return v;
}

double PanelCompressor::SetParamReleaseTime(double v)
{
    if(v < release_time_min)
    {
        v = release_time_min;
    }
    else if(v > release_time_max)
    {
        v = release_time_max;
    }
    double sv = (v - release_time_min) * (1/release_time_step);
    wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_RELEASE_TIME),wxSlider);
    sli->SetValue(sv);
    wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_RELEASE_TIME),wxTextCtrl);
    txt->SetValue(mDoubleToString(v));
    param.release_time = v;
    param_event.SetReleaseTime(v);
    return v;
}

double PanelCompressor::SetParamPostGain(double v)
{
    if(v < postgain_min)
    {
        v = postgain_min;
    }
    else if(v > postgain_max)
    {
        v = postgain_max;
    }
    double sv = (v - postgain_min) * (1/postgain_step);
    wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_POSTGAIN),wxSlider);
    sli->SetValue(sv);
    wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_POSTGAIN),wxTextCtrl);
    txt->SetValue(mDoubleToString(v));
    param.postgain = v;
    param_event.SetPostGain(v);
    return v;
}

bool PanelCompressor::SetParamEnable(bool v)
{
    wxCheckBox *chk = wxDynamicCast(FindWindowById(ID_CHK_SWITCH),wxCheckBox);
    chk->SetValue(v);
    param.enable = v;
    param_event.SetEnable(v);
    return v;
}

double PanelCompressor::GetParamAttackTime() { return param.attack_time; }
double PanelCompressor::GetParamThreshold() { return param.threshold; }
double PanelCompressor::GetParamReleaseTime() { return param.release_time; }
double PanelCompressor::GetParamPostGain() { return param.postgain; }
double PanelCompressor::GetParamRatio() { return param.ratio; }
bool PanelCompressor::GetParamEnable() { return param.enable; }


void PanelCompressor::SetPresetIndex(const unsigned int index)
{
    wxChoice *cmb = wxDynamicCast(FindWindowById(ID_CHO_PRESET),wxChoice);
    if(index < cmb->GetCount())
    {
        select_index = index;
        param_event.SetPresetIndex(select_index);
        cmb->SetSelection(index);
        preset_node = SelectPreset(cmb->GetString(index));
    }
}

int PanelCompressor::GetPresetIndex()
{
    return select_index;
}

void PanelCompressor::TrigerEvent(int ev)
{
    switch(ev)
    {
        case EV_ATTACK_TIME:
        {
            param_event.SetEventType(myEVT_COMPRESSOR_ATTACK_TIME);
            param_event.SetAttackTime(param.attack_time);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_attack_time, mDoubleToString(param.attack_time).c_str());
        }
        break;
        case EV_THRESHOLD:
        {
            param_event.SetEventType(myEVT_COMPRESSOR_THRESHOLD);
            param_event.SetThreshold(param.threshold);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_threshold, mDoubleToString(param.threshold).c_str());
        }
        break;
        case EV_RATIO:
        {
            param_event.SetEventType(myEVT_COMPRESSOR_RATIO);
            param_event.SetRatio(param.ratio);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_ratio, mDoubleToString(param.ratio).c_str());
        }
        break;
        case EV_RELEASE_TIME:
        {
            param_event.SetEventType(myEVT_COMPRESSOR_RELEASE_TIME);
            param_event.SetReleaseTime(param.release_time);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_release_time, mDoubleToString(param.release_time).c_str());
        }
        break;
        case EV_POSTGAIN:
        {
            param_event.SetEventType(myEVT_COMPRESSOR_POSTGAIN);
            param_event.SetPostGain(param.postgain);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_postgain, mDoubleToString(param.postgain).c_str());
        }
        break;
        case EV_ENABLE:
        {
            param_event.SetEventType(myEVT_COMPRESSOR_ENABLE);
            param_event.SetEnable(param.enable);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_enable, param.enable ? "1" : "0");
        }
        break;
    }
}


wxXmlNode *PanelCompressor::SelectPreset(wxString name)
{
    double attack_time = param.attack_time;
    double threshold = param.threshold;
    double release_time = param.release_time;
    double postgain = param.postgain;
    double ratio = param.ratio;
    bool enable = param.enable;

    wxString str;
    wxXmlNode *child;
    child = root_node->GetChildren();
    while(child)
    {
        if(strcmp(child->GetName().c_str(), name.c_str()) == 0)
        {
            break;
        }
        child = child->GetNext();
    }

    if(DataSave::NodeAttributesGetValue(child,attr_name_param_enable,str))
    {
        int v;
        if(str.ToInt(&v))
        {
            enable = v ? true : false;
        }
    }

    if(DataSave::NodeAttributesGetValue(child,attr_name_param_attack_time,str))
    {
        double v;
        if(str.ToDouble(&v))
        {
            attack_time = v;
        }
    }

    if(DataSave::NodeAttributesGetValue(child,attr_name_param_threshold,str))
    {
        double v;
        if(str.ToDouble(&v))
        {
            threshold = v;
        }
    }

    if(DataSave::NodeAttributesGetValue(child,attr_name_param_release_time,str))
    {
        double v;
        if(str.ToDouble(&v))
        {
            release_time = v;
        }
    }

    if(DataSave::NodeAttributesGetValue(child,attr_name_param_postgain,str))
    {
        double v;
        if(str.ToDouble(&v))
        {
            postgain = v;
        }
    }

    if(DataSave::NodeAttributesGetValue(child,attr_name_param_ratio,str))
    {
        double v;
        if(str.ToDouble(&v))
        {
            ratio = v;
        }
    }

    SetParamEnable(enable);
    SetParamAttackTime(attack_time);
    SetParamThreshold(threshold);
    SetParamReleaseTime(release_time);
    SetParamPostGain(postgain);
    SetParamRatio(ratio);

    // if(child == NULL)
    // {
    //     child = new wxXmlNode(wxXML_ELEMENT_NODE,name);
    //     WriteToXML(child);
    //     root_node->AddChild(child);
    // }

    return child;
}

void PanelCompressor::PresetListClear(void)
{
    wxChoice *cmb = wxDynamicCast(FindWindowById(ID_CHO_PRESET),wxChoice);
    if(cmb)
    {
        cmb->Clear();
        preset_node = nullptr;
    }
}

void PanelCompressor::AddPresetList(const wxString &preset_name)
{
    wxChoice *cmb = wxDynamicCast(FindWindowById(ID_CHO_PRESET),wxChoice);
    if(cmb)
    {
        cmb->Append(preset_name);
    }
}

wxXmlNode *PanelCompressor::SaveCurrentParamsToNewPreset(wxXmlNode *root, const wxString &new_preset_name,int &is_same)
{
    wxXmlNode *child = nullptr;
    is_same = 0;
    if((root != nullptr) && (new_preset_name.empty() == false))
    {
        //查找有没有名字相同的预设
        child = root->GetChildren();
        while(child)
        {
            if(strcmp(child->GetName().c_str(), new_preset_name.c_str()) == 0)
            {
                is_same = 1;
                return nullptr;
            }
            child = child->GetNext();
        }
        child = new wxXmlNode(wxXML_ELEMENT_NODE,new_preset_name);
        WriteToXML(child);
        root->AddChild(child);
        wxChoice *cmb = wxDynamicCast(FindWindowById(ID_CHO_PRESET),wxChoice);
        if(cmb)
        {
            cmb->Append(new_preset_name);
        }
    }
    return child;
}

wxXmlNode *PanelCompressor::WriteToXML(wxXmlNode *node)
{
    if(node)
    {
        DataSave::NodeAttributesSetValue(node, attr_name_param_enable, param.enable ? "1" : "0");
        DataSave::NodeAttributesSetValue(node, attr_name_param_threshold, mDoubleToString(param.threshold).c_str(), true);
        DataSave::NodeAttributesSetValue(node, attr_name_param_release_time, mDoubleToString(param.release_time).c_str(), true);
        DataSave::NodeAttributesSetValue(node, attr_name_param_postgain, mDoubleToString(param.postgain).c_str(), true);
        DataSave::NodeAttributesSetValue(node, attr_name_param_ratio, mDoubleToString(param.ratio).c_str(), true);
        DataSave::NodeAttributesSetValue(node, attr_name_param_attack_time, mDoubleToString(param.attack_time).c_str(), true);
    }
    return node;
}